package rad.framework.mda.jpagen.actions;

import rad.framework.mda.generator.Console;
import rad.framework.mda.generator.util.StereotypeHelper;
import rad.framework.mda.util.ModelUtil;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.impl.DynamicEObjectImpl;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;

/**
 * @author boudyacho
 * 
 */
public class AddAttributeOverrideActionExtension extends
		BaseUtiltiyActionExtension {

	protected static final String ATTRIBUTE_OVERRIDES = "javax.persistence.AttributeOverrides";

	public void fillContextMenu(IMenuManager aMenu) {
		getSubMenu(aMenu).add(new AddAttributeOverrideAction());
	}

	protected void execute(Class clazz) {
		if (StereotypeHelper
				.isStereotypeApplied(clazz, StereotypeHelper.ENTITY)) {
			EList<NamedElement> list = clazz.getMembers();
			for (NamedElement namedElement : list) {
				if (namedElement instanceof Property) {
					execute((Property) namedElement);
				}
			}
		}
	}

	protected void execute(Property property) {
		if (ModelUtil.isStereotypeApplied(property,
				EMBEDDED)) {
			applyAttributeOverrides(property);
			Console.getStream().println(
					"Added " + ATTRIBUTE_OVERRIDES + " - "
							+ property.getQualifiedName());
		}
	}

	private void applyAttributeOverrides(Property element) {
		Stereotype stereotype = (Stereotype) ModelUtil.getProfileElement(
				element, ATTRIBUTE_OVERRIDES);
		if (stereotype != null) {
			if (ModelUtil.isStereotypeApplied(element, ATTRIBUTE_OVERRIDES)) {
				element.unapplyStereotype(stereotype);
			}
			EObject appliedStereotype = element.applyStereotype(stereotype);
			addAttributeOverrides(element, appliedStereotype);
		}
	}

	private void addAttributeOverrides(Property element, EObject stereotype) {
		String prefix = NameUtil.getAbbreviation(element);
		Class type = (Class) element.getType();
		EList<NamedElement> list = type.getMembers();
		for (NamedElement namedElement : list) {
			if (namedElement instanceof Property) {
				addAttributeOverride((Property) namedElement, stereotype,
						prefix);
			}
		}
	}

	private void addAttributeOverride(Property embedded,
			EObject stereotypeApplication, String prefix) {
		DynamicEObjectImpl override = createChild(stereotypeApplication);
		addChild(stereotypeApplication, override, "value");
		setAttribute(override, "name", embedded.getName());

		DynamicEObjectImpl column = createChild(override);
		setAttribute(override, "column", column);
		setAttribute(column, "name", prefix + "_"
				+ NameUtil.getAbbreviation(embedded));
		if ("String".equals(embedded.getType().getName())) {
			setAttribute(column, "length", 255);
		}
	}

	private class AddAttributeOverrideAction extends BaseUtilityAction {
		private static final String LABEL = "Add Attribute Override Stereotypes";

		public AddAttributeOverrideAction() {
			super(LABEL);
		}
	}
}
